package cn.aws360.boot.wechat.biz.mp.handler;

import cn.aws360.boot.base.api.utils.FileUtils;
import cn.aws360.boot.extend.open.api.pojo.response.ItemModel;
import cn.aws360.boot.extend.open.biz.service.ChatService;
import cn.aws360.boot.extend.open.biz.service.HotsService;
import cn.aws360.boot.extend.open.biz.service.RecommendService;
import cn.aws360.boot.wechat.api.constant.enums.WxmMsgEnum;
import cn.aws360.boot.wechat.api.pojo.request.WxmCorpusQuery;
import cn.aws360.boot.wechat.api.pojo.response.WxmCorpusModel;
import cn.aws360.boot.wechat.biz.mp.builder.WxMpOutBuilder;
import cn.aws360.boot.wechat.biz.service.WxMpPortalService;
import cn.aws360.boot.wechat.biz.service.WxmCorpusService;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.api.WxConsts.XmlMsgType;
import me.chanjar.weixin.common.session.WxSessionManager;
import me.chanjar.weixin.mp.api.WxMpMessageHandler;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
import org.springframework.stereotype.Component;

import java.io.File;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * @author junnan
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class WxMpMsgHandler implements WxMpMessageHandler {

    private final ChatService chatService;
    private final HotsService hotsService;
    private final RecommendService recommendService;
    private final WxmCorpusService wxmCorpusService;
    private final WxMpPortalService mpPortalService;
    private final static String MSG_TYPE_UN_SUPPORT = "消息类型暂不支持哟，请试试文字或语音聊天吧~";

    @Override
    public WxMpXmlOutMessage handle(WxMpXmlMessage mpXmlMessage, Map<String, Object> context,
                                    WxMpService mpService, WxSessionManager wxSessionManager) {
        String msgType = mpXmlMessage.getMsgType();
        if (!Arrays.asList(XmlMsgType.TEXT, XmlMsgType.VOICE).contains(msgType)) {
            return WxMpOutBuilder.buildText(mpXmlMessage, MSG_TYPE_UN_SUPPORT);
        }

        // 仅支持文字和语音识别的文字
        String input = XmlMsgType.VOICE.equals(msgType) ? mpXmlMessage.getRecognition() : mpXmlMessage.getContent();

        // 1. 优先数据库配置
        WxMpXmlOutMessage outMessage = buildOutMsg4Db(mpXmlMessage, mpService, input);

        // 2. 其次关键词配置
        if (ObjectUtil.isNull(outMessage)) {
            outMessage = buildOutMsg4Key(mpXmlMessage, mpService, input);
        }

        // 3. 最后机器人配置
        if (ObjectUtil.isNull(outMessage)) {
            outMessage = buildOutMsg4Boot(mpXmlMessage, input);
        }

        return outMessage;
    }

    private WxMpXmlOutMessage buildOutMsg4Db(WxMpXmlMessage mpXmlMessage, WxMpService mpService, String input) {
        WxMpXmlOutMessage outMessage = null;
        String appId = mpService.getWxMpConfigStorage().getAppId();
        WxmCorpusQuery wxmCorpusQuery = WxmCorpusQuery.builder().appId(appId).input(input).build();
        List<WxmCorpusModel> modelList = wxmCorpusService.findList(wxmCorpusQuery);
        if (modelList != null && modelList.size() > 0) {
            WxmCorpusModel wxmCorpusModel = modelList.get(0);
            if (ObjectUtil.isNotNull(wxmCorpusModel)) {
                WxmMsgEnum wxmMsgEnum = WxmMsgEnum.getEnum(wxmCorpusModel.getOutType());
                if (ObjectUtil.isNotNull(wxmMsgEnum)) {
                    String outDetail = wxmCorpusModel.getOutDetail();
                    String outMediaId = wxmCorpusModel.getOutMediaId();
                    String outMediaTitle = wxmCorpusModel.getOutMediaTitle();
                    String outMediaDescription = wxmCorpusModel.getOutMediaDescription();
                    String outMediaUrl = wxmCorpusModel.getOutMediaUrl();
                    String outMediaPic = wxmCorpusModel.getOutMediaPic();
                    switch (wxmMsgEnum) {
                        case TEXT:
                            outMessage = WxMpOutBuilder.buildText(mpXmlMessage, outDetail);
                            break;
                        case VOICE:
                            outMessage = WxMpOutBuilder.buildVoice(mpXmlMessage, outMediaId);
                            break;
                        case IMAGE:
                            outMessage = WxMpOutBuilder.buildImage(mpXmlMessage, outMediaId);
                            break;
                        case VIDEO:
                            outMessage = WxMpOutBuilder.buildVideo(mpXmlMessage, outMediaId, outMediaTitle, outMediaDescription);
                            break;
                        case MUSIC:
                            outMessage = WxMpOutBuilder.buildMusic(mpXmlMessage, outMediaId, outMediaTitle, outMediaDescription, outMediaUrl);
                            break;
                        case NEWS:
                            outMessage = WxMpOutBuilder.buildNews(mpXmlMessage, outMediaUrl, outMediaTitle, outMediaDescription, outMediaPic);
                            break;
                        default:
                            break;
                    }
                }
            }
        }
        return outMessage;
    }

    private WxMpXmlOutMessage buildOutMsg4Key(WxMpXmlMessage mpXmlMessage, WxMpService mpService, String input) {
        WxMpXmlOutMessage outMessage = null;
        switch (input) {
            case "图片":
                outMessage = buildOutMsg4ApiImage(mpXmlMessage, mpService);
                break;
            case "音乐":
                outMessage = buildOutMsg4ApiMusic(mpXmlMessage, mpService);
                break;
            case "新闻":
                outMessage = buildOutMsg4ApiNews(mpXmlMessage);
                break;
            default:
                break;
        }
        return outMessage;
    }

    private WxMpXmlOutMessage buildOutMsg4Boot(WxMpXmlMessage mpXmlMessage, String input) {
        WxMpXmlOutMessage outMessage = null;
        String tlChatRes = chatService.getTlChatRes(input);
        if (StrUtil.isNotBlank(tlChatRes)) {
            outMessage = WxMpOutBuilder.buildText(mpXmlMessage, tlChatRes);
        }
        return outMessage;
    }

    private WxMpXmlOutMessage buildOutMsg4ApiImage(WxMpXmlMessage mpXmlMessage, WxMpService mpService) {
        ItemModel recImage = recommendService.getRecImage();
        if (ObjectUtil.isNotNull(recImage)) {
            File tmpFile = FileUtils.downFile(recImage.getPic(), "png");
            String mediaId = mpPortalService.uploadTempMedia(mpService, WxConsts.MediaFileType.IMAGE, tmpFile);
            return WxMpOutBuilder.buildImage(mpXmlMessage, mediaId);
        }
        return null;
    }

    private WxMpXmlOutMessage buildOutMsg4ApiMusic(WxMpXmlMessage mpXmlMessage, WxMpService mpService) {
        List<ItemModel> musicList = recommendService.getRecMusicList();
        if (CollUtil.isNotEmpty(musicList)) {
            ItemModel itemModel = RandomUtil.randomEle(musicList);
            File tmpFile = FileUtils.downFile(itemModel.getPic(), "png");
            String mediaId = mpPortalService.uploadTempMedia(mpService, WxConsts.MediaFileType.IMAGE, tmpFile);
            return WxMpOutBuilder.buildMusic(mpXmlMessage, mediaId, itemModel.getTitle(), itemModel.getSummary(), itemModel.getUrl());
        }
        return null;
    }

    private WxMpXmlOutMessage buildOutMsg4ApiNews(WxMpXmlMessage mpXmlMessage) {
        ItemModel recNews = recommendService.getRecNews();
        if (ObjectUtil.isNotNull(recNews)) {
            return WxMpOutBuilder.buildNews(mpXmlMessage, recNews.getUrl(),
                    recNews.getTitle(), recNews.getSummary(), recNews.getPic());
        }
        return null;
    }

}
